package cn.lenqq;

import cn.lenqq.Utils.MybatisUtil;
import cn.lenqq.Utils.RSAUtil;
import cn.lenqq.mapper.PwdSecretMapper;
import cn.lenqq.pojo.PwdSecret;
import org.apache.ibatis.session.SqlSession;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.logging.Logger;

public class PasswordManager extends JFrame {

    private static final Logger log = Logger.getLogger(PasswordManager.class.getName());

    private JTable table;

    private JTextArea decryptArea;

    private String encryptPwd ;

    private Object[][] data;

    private DefaultTableModel tableModel;

    public PasswordManager(){
        setTitle("密码箱");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(1000, 600);
        setVisible(true);
        setLayout(new GridLayout(3, 1));

        String[] tableHeadArr = {"来源","密文","创建时间"};


        data = initTableData();


        tableModel = new DefaultTableModel(data,tableHeadArr);

        table = new JTable(tableModel);
        table.setPreferredScrollableViewportSize(new Dimension(1000,300));
        table.setFillsViewportHeight(true);
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        table.getSelectionModel().addListSelectionListener((e) -> {decryptCipher();});

        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane);

        JPanel convertPanel = new JPanel();
        convertPanel.setLayout(new FlowLayout(FlowLayout.CENTER));

        TitledBorder convertBorder = BorderFactory.createTitledBorder("Convert");
        convertPanel.setBorder(convertBorder);

        JLabel sourceLabel = new JLabel("来源：",JLabel.TRAILING);
        JTextField sourceField = new JTextField(12);
        sourceLabel.setLabelFor(sourceField);
        convertPanel.add(sourceLabel);
        convertPanel.add(sourceField);

        JLabel pwdLabel = new JLabel("密码：",JLabel.TRAILING);
        JTextField pwdField = new JTextField(18);
        pwdLabel.setLabelFor(pwdField);
        convertPanel.add(pwdLabel);
        convertPanel.add(pwdField);

        JLabel cipherLabel = new JLabel("密文：",JLabel.TRAILING);
        JTextField cipherField = new JTextField(18);
        cipherLabel.setLabelFor(cipherField);

        JButton convertButton = new JButton("转换 →");
        convertButton.setVerticalTextPosition(AbstractButton.CENTER);
        convertButton.addActionListener((evn) -> {
            String pwd = pwdField.getText();
            encryptPwd = RSAUtil.encrypt(pwd);

            cipherField.setText(encryptPwd.substring(0,16));
        });


        convertPanel.add(convertButton);
        convertPanel.add(cipherLabel);
        convertPanel.add(cipherField);

        JButton saveButton = new JButton("保存 ⬆");
        saveButton.setVerticalTextPosition(AbstractButton.CENTER);

        saveButton.addActionListener((evn) -> {
            String source = sourceField.getText();

            LocalDateTime now = LocalDateTime.now();
            long epochMilli = now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
            PwdSecret pwdSecret = new PwdSecret(source,encryptPwd,1,epochMilli);
            addPwdSecret(pwdSecret);

            String nowStr = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            tableModel.insertRow(0, new Object[]{source,encryptPwd,nowStr});

        });

        convertPanel.add(saveButton);

        add(convertPanel);

        JPanel decryptPanel = new JPanel();
        decryptPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
        TitledBorder decryptBorder = BorderFactory.createTitledBorder("Decrypt");
        decryptPanel.setBorder(decryptBorder);

        decryptArea = new JTextArea(3,65);
        decryptArea.setForeground(Color.RED);
        decryptArea.setFont(new Font("方正黑体", Font.BOLD, 16));
        decryptArea.setEditable(false);

        decryptPanel.add(decryptArea);
        add(decryptPanel);

    }

    private void addPwdSecret(PwdSecret pwdSecret) {
        SqlSession sqlSession = MybatisUtil.getSqlSessionFactory().openSession();

        PwdSecretMapper pwdSecretMapper = sqlSession.getMapper(PwdSecretMapper.class);
        int result = pwdSecretMapper.add(pwdSecret);
        sqlSession.commit();
        sqlSession.close();
    }

    private Object[][] initTableData() {
        SqlSession sqlSession = MybatisUtil.getSqlSessionFactory().openSession();
        PwdSecretMapper pwdSecretMapper = sqlSession.getMapper(PwdSecretMapper.class);
        List<PwdSecret> pwdSecretList = pwdSecretMapper.all();
        Object[][] data = null;
        if(pwdSecretList.size() > 0){
            data = new Object[pwdSecretList.size()][3];
            for (int i = 0; i < pwdSecretList.size(); i++) {
                LocalDateTime createTime = Instant.ofEpochMilli(pwdSecretList.get(i).getCreateTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
                String createTimeStr = createTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

                data[i] = new Object[] {pwdSecretList.get(i).getSource(),pwdSecretList.get(i).getCipherText(),createTimeStr};
            }
        }


        sqlSession.close();

        return data;
    }

    private void decryptCipher() {
        for (int selectedRow : table.getSelectedRows()) {
            decryptArea.setText(String.format(tableModel.getValueAt(selectedRow,0) + " 的密码是：" + RSAUtil.decrypt(String.valueOf(tableModel.getValueAt(selectedRow,1)))));
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new PasswordManager();
        });
    }
}
